package bots.lookahead;

import model.Field;
import model.Figure;
import model.GameType;
import util.Bag;

import java.util.concurrent.ForkJoinPool;

/**
 * @author Alex Vikharev alex.vikharev@gmail.com
 *         created 17.02.12
 */
public class LightLookAheadBot extends AbstractLookAheadBot {
    private final int movesToLook;
    private boolean adjusting;
    private int adjustingCounter;
    private int movesNotToLook;
    private Bag<Integer> wins = new Bag<>();

    public LightLookAheadBot(GameType gameType, String name, int movesToLook, ForkJoinPool pool) {
        this(gameType, name, movesToLook, pool, true);
    }

    public void reset(){
        movesNotToLook = 4;
        adjustingCounter = 0;
        adjusting = true;
    }

    public LightLookAheadBot(GameType gameType, String name, int movesToLook, ForkJoinPool pool, boolean adjusting) {
        super(name, gameType, pool);
        this.movesToLook = movesToLook;
        adjustingCounter = 0;
        movesNotToLook = 6;
        this.adjusting = adjusting;
    }

    @Override
    public model.Position setFigure(Field field, Figure figure) {
        log.debug("Given: " + figure);
        final int usedFigures = field.getUsedFigures().size();
        if (usedFigures < 2) {
            return setRandomFigure(field, figure);
        } else if (usedFigures < movesNotToLook) {
            Task task = new Task(field, figure, Math.min(1, movesToLook));
            Result result = pool.invoke(task);
            return result.move;
        } else {
            Task task = new Task(field, figure, movesToLook);
            Result result = pool.invoke(task);
            if (usedFigures - movesNotToLook < 2) {
                adjust(result);
            }
            if (result.pos == PositionType.WIN) {
                wins.put(usedFigures);
            }
            return result.move;
        }
    }

    private void adjust(final Result result) {
        if (adjusting) {
            if (result.pos == PositionType.WIN) {
                adjusting = false;
                log.info("[" + name + "] Adjusting finished, skip moves: " + movesNotToLook);
                log.info("[" + name + "] Wins statistics: " + wins);
            } else {
                adjustingCounter++;
                if (adjustingCounter == 100) {
                    movesNotToLook++;
                    log.info("[" + name + "] Adjusting in progress, increasing skip moves count to " + movesNotToLook);
                    adjustingCounter = 0;
                }
            }
        }
    }

}
